# -*- coding: utf-8 -*-
#
import logging

from flask import current_app
from celery import subtask
from celery.signals import (
    worker_ready, worker_shutdown, after_setup_logger, task_failure
)

from apps.extensions import cache
from apps.ops.celery.decorator import (
    get_after_app_ready_tasks, get_after_app_shutdown_clean_tasks
)
from .logger import CeleryTaskFileHandler


@worker_ready.connect
def on_app_ready(sender=None, headers=None, **kwargs):
    if cache.get("CELERY_APP_READY") == 1:
        return
    cache.set("CELERY_APP_READY", 1, timeout=10)
    tasks = get_after_app_ready_tasks()
    current_app.logger.debug("Work ready signal recv")
    current_app.logger.debug("Start need start task: [{}]".format(", ".join(tasks)))
    for task in tasks:
        subtask(task).delay()


@worker_shutdown.connect
def on_app_shutdown(sender=None, **kwargs):
    if cache.get("CELERY_APP_SHUTDOWN") == 1:
        return
    cache.set("CELERY_APP_SHUTDOWN", 1, timeout=10)
    tasks = get_after_app_shutdown_clean_tasks()
    current_app.logger.debug("Worker shutdown signal recv")
    current_app.logger.debug("Clean period tasks: [{}]".format(', '.join(tasks)))
    for task in tasks:
        # 本次关闭是不会执行, 下次启动时会执行
        subtask(task).delay()


@after_setup_logger.connect
def add_celery_logger_handler(sender=None, logger=None, loglevel=None, format=None, **kwargs):
    if not logger:
        return
    formatter = logging.Formatter(format)
    task_handler = CeleryTaskFileHandler()
    task_handler.setLevel(loglevel)
    task_handler.setFormatter(formatter)
    logger.addHandler(task_handler)


# Celery task raises an unhandled exception.
@task_failure.connect
def celery_error_handler(sender, exception, **_):
    exception_name = exception.__class__.__name__
    task_module = sender.name
    current_app.logger.error('{} exception in {}'.format(exception_name, task_module))
